package com.atguigu.lease.web.app.service.impl;


import com.atguigu.lease.common.advice.CostomReturnException;
import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.jwt.JwtUtil;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.service.UserInfoService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.atguigu.lease.web.app.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private UserInfoService userInfoService;

    @Override
    public void getCode(String phone) {
        //判断手机号是否为空
        if (ObjectUtils.isEmpty(phone)) {
            throw new CostomReturnException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }
        //拼接phone作为key
        String redisKey = RedisConstant.APP_LOGIN_PREFIX + phone;
        //判断手机号短时间内是否发送过验证码请求
        Integer appLoginCodeResendTimeSec = RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC; //限制请求时间间隔
        Integer appLoginCodeTtlSec = RedisConstant.APP_LOGIN_CODE_TTL_SEC;//验证码保存时间
        Long redisTemplateExpire = redisTemplate.getExpire(redisKey, TimeUnit.SECONDS);//以存储时间
        if (appLoginCodeTtlSec - redisTemplateExpire < appLoginCodeResendTimeSec) {
            //频繁发送，拒绝发送请求，
            throw new CostomReturnException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
        }
        //生成验证码，六位数
        Random random = new Random();
        int code = random.nextInt(900000) + 100000;

        //保存到redis
        redisTemplate.opsForValue().set(redisKey,code,RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC,TimeUnit.SECONDS);
        //发送给用户
        System.out.println(code);

    }

    @Override
    public String login(LoginVo loginVo) {
        //判断手机号是否为空
        if (ObjectUtils.isEmpty(loginVo.getPhone())) {
            throw new CostomReturnException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }
        //判断验证码是否为空
        if (ObjectUtils.isEmpty(loginVo.getCode())) {
            throw new CostomReturnException(ResultCodeEnum.APP_LOGIN_CODE_EMPTY);
        }
        //判断验证码是否过期
        //拼接key
        String redisKey = RedisConstant.APP_LOGIN_PREFIX + loginVo.getPhone();
        Integer code = (Integer) redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtils.isEmpty(code)) {
            throw new CostomReturnException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }
        //判断验证码是否正确
        if (!loginVo.getCode().equals(code.toString())) {
            throw new CostomReturnException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }
        //判断用户是否被禁用
        LambdaQueryWrapper<UserInfo> lambdaQueryWrapper= new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserInfo::getPhone,loginVo.getPhone());
        UserInfo userInfo = userInfoService.getOne(lambdaQueryWrapper);
        if (userInfo.getStatus() == BaseStatus.DISABLE) {
            throw new CostomReturnException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
        }
        //判断手机号是否注册
        if (ObjectUtils.isEmpty(userInfo)) {
             userInfo =new UserInfo();
            //没注册，注册一个
            userInfo.setPhone(loginVo.getPhone());
            //添加默认用户名
            String nickName = "用户-" + loginVo.getPhone().substring(loginVo.getPhone().length() - 4);
            userInfo.setNickname(nickName);
            userInfoService.save(userInfo);
        }
        System.out.println(userInfo.getId());
        //通过，生成token 发给前端
        return JwtUtil.createToken(userInfo.getId(), userInfo.getPassword());
    }

    @Override
    public UserInfoVo info(String accessToken) {
        //获取token存入的id
        Claims claims = JwtUtil.parseToken(accessToken);
        Integer userId = (Integer) claims.get("userId");
        //查询用户信息
        UserInfo userInfo = userInfoService.getById(userId);
        //返回信息
        return new UserInfoVo(userInfo.getNickname(),userInfo.getAvatarUrl());
    }
}
